package org.akomantoso.core.io.util.group;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.akomantoso.core.data.Adjournment;
import org.akomantoso.core.data.DebateSection;
import org.akomantoso.core.data.OralStatements;
import org.akomantoso.core.data.Prayers;
import org.akomantoso.core.data.group.SpeechSection;
import org.akomantoso.core.io.Input;
import org.akomantoso.core.io.InputConstants;
import org.akomantoso.core.io.util.Instantiator;

/**
 * @author <a href="mailto:jacques.militello@gmail.com">Jacques Militello</a>
 */
public final class SpeechSectionGroup {

	private SpeechSectionGroup() {
	}

	public static final Map<String, Instantiator<SpeechSection>> MAP;

	public static void read(Input in, List<SpeechSection> items) throws IOException {
		SpeechSection speechSection = null;
		final String localName = in.getLocalName();
		int eventType;
		
		while (true) {
			eventType = in.readNext();
			if (eventType == InputConstants.START_ELEMENT) {
				items.add(speechSection = instantiate(in.getLocalName()));
				speechSection.readExternal(in);
			}
			if (in.getEventType() == InputConstants.END_ELEMENT && localName.equals(in.getLocalName())) {
				return;
			}
		}
	}

	private static SpeechSection instantiate(String elementName) {
		final Instantiator<? extends SpeechSection> instatiator = MAP.get(elementName);
		if (instatiator == null) {
			throw new RuntimeException("Tag [" + elementName + "] not supported for SpeechSection ?!?");
		}
		return instatiator.instantiate();

	}

	static {

		Map<String, Instantiator<SpeechSection>> temp = new HashMap<String, Instantiator<SpeechSection>>();

		// debateSection
		temp.put(DebateSection.ELEMENT, new Instantiator<SpeechSection>() {
			public DebateSection instantiate() {
				return new DebateSection();
			}
		});

		// prayers
		temp.put(Prayers.ELEMENT, new Instantiator<SpeechSection>() {
			public Prayers instantiate() {
				return new Prayers();
			}
		});

		// oralStatements
		temp.put(OralStatements.ELEMENT, new Instantiator<SpeechSection>() {
			public OralStatements instantiate() {
				return new OralStatements();
			}
		});

		// adjournment
		temp.put(Adjournment.ELEMENT, new Instantiator<SpeechSection>() {
			public Adjournment instantiate() {
				return new Adjournment();
			}
		});

		MAP = Collections.unmodifiableMap(temp);
	}
}